package cn.bearspark.common.parse;

import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/**
 * 容纳解析器的管道
 *
 * @author f
 */
public abstract class Pipeline<CTX extends Context> {

    /**
     * 解析器的集合
     */
    private final List<Parser<CTX>> parserList = new ArrayList<>();

    /**
     * 解析的上下文
     */
    @Getter
    @Setter
    private CTX context;

    /**
     * 可链式调用的 添加处理器 的方法
     *
     * @param parser 待添加处理器
     * @return 添加处理器的管道
     */
    public final Pipeline<CTX> add(Parser<CTX> parser) {
        parserList.add(parser);
        parser.setPipeline(this);
        return this;
    }

    /**
     * 解析源字符串
     *
     * @param src 源字符串
     */
    public final CTX parse(String src) {
        if (src == null || src.trim().isEmpty()) {
            return null;
        }
        context = getContext(src);
        context.setBody(src);
        for (Parser<CTX> parser : parserList) {
            parser.parse();
        }
        return context;
    }

    /**
     * 获取上下文
     *
     * @param src 源字符串
     */
    protected abstract CTX getContext(String src);

    /**
     * 反解析目标字符串
     *
     * @param context 解析的上下文
     */
    public String unparse(CTX context) {
        if (context == null || context.getBody() == null || context.getBody().trim().isEmpty()) {
            return null;
        }
        this.context = context;
        ListIterator<Parser<CTX>> iterator = parserList.listIterator(parserList.size());
        while (iterator.hasPrevious()) {
            iterator.previous().unparse();
        }
        return context.getBody();
    }

}
